package org.jmc.refmanager.util;

import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.wicket.Component;
import org.jmc.refmanager.domain.model.OrgUnit.Complement;
import org.jmc.refmanager.web.wicket.model.EnumMessageKeyProvider;

public final class Util {
	public static final String BLANK = "";
	public static final String NULL = "null";

	private static final String alphanumerical = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	private static final String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	private static final String numbers = "0123456789";
	private static final Random randomizer = new Random();

	/**
	 * 
	 * @param component
	 * @param complementString
	 * @return
	 */
	public static String getComplementLabel(Component component, Object complementString) {
		String complementValue = null;
		if (complementString != null) {
			Complement complement = Complement.valueOf(complementString.toString());
			String key = EnumMessageKeyProvider.getMessageKey(complement, Complement.class);
			complementValue = component.getString(key);
		}
		
		return complementValue;
	}
	
	/**
	 * Genere un code de service sur 8 positions.
	 * Une lettre suivie de 7 chiffres aleatoires.
	 * 
	 * @return
	 */
	public static String generateCodeUO() {
		return generateRandomAccountId(1, 7, false);
	}

	/**
	 * Generates a random account identifier for IdM user.
	 * @param nbOfLetters Number of letters (at the beginning if not randomized)
	 * @param nbOfNumbers Number of numerical chars (following if not randomized)
	 * @param random allows alphabet to be mixed
	 * 
	 * @return new account identifier
	 */
	private static final String generateRandomAccountId(int nbOfLetters, int nbOfNumbers, boolean random) {
		if (nbOfLetters<0 || nbOfNumbers<0 || (nbOfLetters==0 && nbOfNumbers==0)) {
			throw new IllegalArgumentException("[TEP] Unable to generate accountId: bad arguments");
		}
		char[] buf = new char[nbOfLetters + nbOfNumbers];
		
		if (random) {
			for (int i = 0; i < buf.length; i++) {
				buf[i] = alphanumerical.charAt(randomizer.nextInt(alphanumerical.length()));
			}
		} else {
			for (int i = 0; i < nbOfLetters; i++) {
				buf[i] = letters.charAt(randomizer.nextInt(letters.length()));
			}
			for (int i = 0; i < nbOfNumbers; i++) {
				buf[nbOfLetters + i] = numbers.charAt(randomizer.nextInt(numbers.length()));
			}
		}
		return new String(buf);
	}


	/**
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isEmptyOrBlank(String value) {
		return value == null || value.trim().length() == 0;
	}
	
	/**
	 * 
	 * @param value
	 * @return
	 */
	public static String getBlankIfNull(String value) {
		if (isEmpty(value)) {
			return BLANK;
		} else {
			return value;
		}
	}

	/**
	 * 
	 * @param value
	 * @return
	 */
	public static String ifNull(Object value, String defaultValue) {
		if (value == null) {
			return defaultValue;
		} else {
			return value.toString();
		}
	}

	/**
	 * 
	 * @param value
	 * @param defaultValue
	 * @return
	 */
	public static String ifNullOrEmpty(Object value, String defaultValue) {
		if (value == null || isEmpty(value.toString())) {
			return defaultValue;
		} else {
			return value.toString();
		}
	}

	/**
	 * 
	 * @param map
	 * @return
	 */
	public static boolean isNullOrEmpty(Map<String, Object> map) {
		return (map == null || map.size() == 0);
	}

	/**
	 * 
	 * @param list
	 * @return
	 */
	public static boolean isNullOrEmpty(List<?> list) {
		return (list == null || list.size() == 0);
	}

	/**
	 * 
	 * @param list
	 * @return
	 */
	public static boolean isNullOrEmpty(Set<?> list) {
		return (list == null || list.size() == 0);
	}

	/**
	 * 
	 * @param value
	 * @return
	 */
	public static boolean notEmpty(String value) {
		return (value != null && value.trim().length() != 0);
	}

	/**
	 * 
	 * @param value
	 * @return
	 */
	public static boolean notEmpty(Object value) {
		return (value != null && value.toString().trim().length() != 0);
	}

	/**
	 * 
	 * @param value
	 * @param message
	 * 
	 * @return
	 */
	public static void notNull(Object value, String message) {
		if (value == null) {
			throw new IllegalArgumentException(message);
		}
	}

	/**
	 * 
	 * @param value
	 * @return
	 */
	public static void notNull(Object value) {
		if (value == null) {
			throw new IllegalArgumentException("Object cannot be null");
		}
	}

	/**
	 * 
	 * @param paramValue
	 * @return
	 */
	public static String getStartWithParameter(String paramValue) {
		if (notEmpty(paramValue)) {
			return paramValue.concat("%");
		} else {
			return null;
		}
	}

	/**
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isEmpty(String value) {
		return (value == null || value.trim().length() == 0);
	}

	/**
	 * <p>
	 * Compares two Strings, returning <code>true</code> if they are equal.
	 * </p>
	 * 
	 * <p>
	 * <code>null</code>s are handled without exceptions. Two <code>null</code>
	 * references are considered to be equal. The comparison is case sensitive.
	 * </p>
	 * 
	 * <pre>
	 * StringUtils.equals(null, null)   = true
	 * StringUtils.equals(null, "abc")  = false
	 * StringUtils.equals("abc", null)  = false
	 * StringUtils.equals("abc", "abc") = true
	 * StringUtils.equals("abc", "ABC") = false
	 * </pre>
	 * 
	 * @see java.lang.String#equals(Object)
	 * @param str1
	 *            the first String, may be null
	 * @param str2
	 *            the second String, may be null
	 * @return <code>true</code> if the Strings are equal, case sensitive, or
	 *         both <code>null</code>
	 */
	public static boolean equals(String str1, String str2) {
		return (str1 == null ? str2 == null : str1.equals(str2));
	}

}
